import * as THREE from "three";
import { threeViewStore } from "../../store/models/data";
import pinia from '../../store/index';
var moveFlag = false;
const store = threeViewStore(pinia);
console.log(store,'store');

/**测距 */
// 接下来解决的问题
// 1.如何点击获取当前点坐标，并画点
// 2.画的点的个数等于二时就画一条线，如果画了第三个点，就清空之前画的点与线
// 3.换算，把数据换算成实际单位的数据，如换算成cm 
export function distance(visible: Boolean) {
    let domContainer = document.getElementById("threeContainer");
    // 使用visible判断当前是选中还是释放状态
    if (visible) {
        domContainer.style.cursor = "crosshair";
        domContainer?.addEventListener("mousedown", onmousedown);
        window.controls.addEventListener("change", onPointerMove);
        domContainer?.addEventListener("mouseup", onPointerClick);
    }
    else {
        domContainer.style.cursor = "default";
        domContainer?.removeEventListener("mouseup", onPointerClick);
        domContainer?.removeEventListener("mousedown", onmousedown);
        window.controls.removeEventListener("change", onPointerMove);
    }
}
function onmousedown() {
    moveFlag = false;//如果鼠标发生了移动，就将moveFlag设置为false,则不再触发onPointerClick方法，即不再绘制点
}
function onPointerMove() {
    moveFlag = true;
}
let pointsArr: number[] = [];
let geometryArr: any = [];
let pointsArrV3: any = [];
let labelText = document.createElement('span');
/**鼠标按下触发事件 */
function onPointerClick(event: any) {
    if (!moveFlag) {
        if (pointsArrV3.length === 2) {
            // 当要开始绘制第三个点时，把存放点坐标的数组清空
            pointsArrV3 = [];
        }
        console.log(event, '点击了');
        const pointer = new THREE.Vector2();
        pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
        pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
        // 得到的pointer是三维坐标
        const raycaster = new THREE.Raycaster();
        raycaster.setFromCamera(pointer, window.camera);
        // var endPosition:THREE.Vector3;
        let position = [];
        const intersects = raycaster.intersectObjects(window.threeScene.children, true);
        console.log(intersects, 'intersects');

        if (intersects.length > 0) {
            let index = 0;
            let x = intersects[index].point.x;
            let y = intersects[index].point.y;
            let z = intersects[index].point.z;
            position.push(x);
            position.push(y);
            position.push(z);
            const vposition = intersects[0].point;
            pointsArrV3.push(vposition);
        }
        console.log(pointsArrV3, 'pointsArrV3----加完');

        // 绘制点
        // 把点击的点的坐标存入数组，根据二维坐标画点
        // 绘制点使用BufferGeometry
        const geometry = new THREE.BufferGeometry();
        const color = new Float32Array([1, 0, 0]);
        console.log(position, 'position3');
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(position, 3));
        geometry.setAttribute('color', new THREE.BufferAttribute(color, 3));
        geometry.computeBoundingSphere();
        // 定义材质
        // 如果需要绘制点线可以被模型遮挡，把depthTest设置为true即可
        const material = new THREE.PointsMaterial({ size: 0.1, vertexColors: true, depthTest: false });
        const drawpoint = new THREE.Points(geometry, material);
        window.threeScene.add(drawpoint);
        geometryArr.push(drawpoint);

        // 如果长度等于2就绘制一条线
        if (pointsArr.length < 6) {
            for (let i = 0; i < position.length; i++) {
                pointsArr.push(position[i]);
            }
            if (pointsArr.length == 6) {
                // 绘制线
                drawLine(pointsArr, event);
            }
        }
        else {
            pointsArr = [];
            // 执行清空上一次绘制的线和两个点的操作
            geometryArr.forEach((item: any, index: any) => {
                if (index != geometryArr.length - 1) {
                    window.threeScene.remove(item);
                }
                else{
                    // 将数组的前length-1个数据都清除掉
                    let curpoint = geometryArr[geometryArr.length - 1];
                    geometryArr = [];
                    geometryArr.push(curpoint);
                }
            })
            // 卸载标签
            labelText.innerHTML = '';
            // 继续加载新点
            for (let i = 0; i < position.length; i++) {
                pointsArr.push(position[i]);
            }
        }
    }
}
/**绘制线 */
function drawLine(pointsArr: any, event: any) {
    console.log(pointsArrV3, 'pointsArrV3');
    const geometry = new THREE.BufferGeometry();
    const color = new Float32Array([1, 0, 0]);
    geometry.setAttribute('position', new THREE.Float32BufferAttribute(pointsArr, 3));
    geometry.setAttribute('color', new THREE.BufferAttribute(color, 3));
    geometry.computeBoundingSphere();
    const material = new THREE.LineBasicMaterial({ vertexColors: true, depthTest: false });
    const line = new THREE.Line(geometry, material);
    line.frustumCulled = false;//这行代码很关键,让屏幕外区域的点,正确显示
    window.threeScene.add(line);
    geometryArr.push(line);
    drawLabel(line, event);
}

/**绘制标签 */
function drawLabel(line: any, event: any) {
    // 绘制标签展示距离，需要计算起点和终点之间的距离。通过与真实环境下的距离进行换算
    // 设置标签展示位置
    labelText.style.position = 'absolute';
    labelText.style.top = '0';
    labelText.style.color = 'red';
    labelText.style.pointerEvents = 'none';
    document.body.appendChild(labelText);
    // 源代码是构建虚线的时候才实时渲染
    line.onBeforeRender = function () {
        // 设置标签位置，实时渲染
        setLabelPosition(labelText, event);
    }
}
/**动态渲染修改标签位置 */
function setLabelPosition(labelText: any, event: any) {
    let pointLabel = new THREE.Vector3().lerpVectors(pointsArrV3[1], pointsArrV3[0], 0)
    pointLabel = WorldtoScreenPosition(pointLabel, event);
    // console.log(pointLabel,'pointLabel');
    
    labelText.style.left = pointLabel.x + 'px';
    labelText.style.top = pointLabel.y + 5 + 'px';
// console.log(labelText.style.top,'labelText.style.top');

    let distance = pointsArrV3[1].distanceTo(pointsArrV3[0]);    // 计算显示的数值
    // 根据两个坐标点计算向量的长度v1(x1,y1,z1),v2(x2,y2,z2),
    // 两点确定的向量长度 =  
    // var dx = v1.x - v2.x; 
    // var dy = v1.y - v2.y; 
    // var dz = v1.z - v2.z;
    // return Math.sqrt( dx * dx + dy * dy + dz * dz );

    labelText.innerHTML = distance.toFixed(2) + 'm'; // toFixed把 Number 四舍五入为指定小数位数的数字
    /** 坐标转换，再把vector3坐标转为屏幕坐标*/
    function WorldtoScreenPosition(pos: any, eve: any) {
        // const worldVector = new THREE.Vector3(pos.x, pos.y, pos.z)
        const standardVector = pos.project(window.camera);// 进行投影转换，不太懂为啥转，里面执行了啥操作
        const widthHalf = eve.view.innerWidth / 2;
        const heightHalf = eve.view.innerHeight / 2;
        return {
            x: Math.round(standardVector.x * widthHalf + widthHalf),
            y: Math.round(-standardVector.y * heightHalf + heightHalf),
            z: 1
        }
    }
}